package com.zmn.oms.common.utils;

import com.zmn.common.utils.date.DateUtil;
import java.util.*;

public class DateTimeUtil {

    private static final String GRAB_FORMAT_DATETIME = "HH:mm:ss:SSS";

    private static final String GRAB_END_FORMAT_DATETIME = "HH:mm";

    /**
     * 判断指定时间是否在区间内
     * 抢单专用
     * @param date
     * @param startTime
     * @param endTime
     * @return
     */
    public static boolean isBetween(Date date, String startTime, String endTime) {
        String baseTime = DateUtil.dateFormatToString(date, GRAB_FORMAT_DATETIME);

        int currentHour = Integer.parseInt(baseTime.substring(0, 2));
        int currentMinute = Integer.parseInt(baseTime.substring(3, 5));
        int currentSecond = Integer.parseInt(baseTime.substring(6, 8));
        int currentMillis = Integer.parseInt(baseTime.substring(9, 12));
        int startHour = Integer.parseInt(startTime.substring(0, 2));
        int startMinute = Integer.parseInt(startTime.substring(3, 5));
        int endHour = Integer.parseInt(endTime.substring(0, 2));
        int endMinute = Integer.parseInt(endTime.substring(3, 5));

        // 判断是否跨0点
        boolean zero = false;
        if (startHour > endHour) {
            zero = true;
        }

        if (zero) {
            if (currentHour > startHour) {
                return true;
            }
            if (currentHour == startHour) {
                if (currentMinute >= startMinute) {
                    return true;
                }
            }
            if (currentHour < startHour) {
                if (currentHour < endHour) {
                    return true;
                }
                if (currentHour == endHour) {
                    if (currentMinute == endMinute) {
                        if (currentSecond == 0) {
                            if (currentMillis == 0) {
                                return true;
                            }
                        }
                    }
                    if (currentMinute < endMinute) {
                        return true;
                    }
                }
            }
            return false;
        } else {
            if (currentHour > startHour) {
                if (currentHour < endHour) {
                    return true;
                }
                if (currentHour == endHour) {
                    if (currentMinute == endMinute) {
                        if (currentSecond == 0) {
                            if (currentMillis == 0) {
                                return true;
                            }
                        }
                    }
                    if (currentMinute < endMinute) {
                        return true;
                    }
                }
                return false;
            }
            if (currentHour == startHour) {
                if (currentHour < endHour) {
                    if (currentMinute >= startMinute) {
                        return true;
                    }
                }
                if (currentHour == endHour) {
                    if (currentMinute >= startMinute) {
                        if (currentMinute == endMinute) {
                            if (currentSecond == 0 ) {
                                if (currentMillis == 0) {
                                    return true;
                                }
                            }
                        } else if (currentMinute < endMinute) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    }

    /**
     * 获取抢单结束时间
     * @param currentDate
     * @param endTime
     * @return
     */
    public static Date getGrabEndTime(Date currentDate, String endTime) {
        int endHour = Integer.parseInt(endTime.substring(0, 2));
        int endMinute = Integer.parseInt(endTime.substring(3, 5));
        Calendar calendar = Calendar.getInstance();
        // HOUR_OF_DAY是24小时制，HOUR是12小时制
        calendar.set(Calendar.HOUR_OF_DAY, endHour);
        calendar.set(Calendar.MINUTE, endMinute);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        if (currentDate.getTime() <= calendar.getTimeInMillis()) {
            return calendar.getTime();
        } else {
            calendar.add(Calendar.DAY_OF_YEAR, 1);
            return calendar.getTime();
        }
    }

    /**
     * 获取指定天数前后日期
     * @param day 正数，未来日期。负数，以前日期
     * @return
     */
    public static Date getAppointDay(int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, day);
        return calendar.getTime();
    }

    /**
     * 获取最新抢单时间
     * @param grabTimeList
     * @return
     */
    public static String getNewestGrabTime(Date currentDate, List<String> grabTimeList) {
        String baseTime = DateUtil.dateFormatToString(currentDate, GRAB_END_FORMAT_DATETIME);
        String abstractTime = baseTime + "~00:00";
        grabTimeList.add(abstractTime);
        Collections.sort(grabTimeList);
        int index = 0;
        for (String time : grabTimeList) {
            if (Objects.equals(time, abstractTime)) {
                break;
            }
            index++;
        }
        if (index == grabTimeList.size() - 1) {
            return grabTimeList.get(0);
        } else {
            return grabTimeList.get(++index);
        }
    }

    /**
     * 得到当前d天后/前的日期时间
     */
    public static Date getBaseDefer(Date baseTime, int days, int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(baseTime);
        calendar.add(Calendar.DAY_OF_YEAR, days);
        calendar.set(Calendar.HOUR_OF_DAY, hours);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 多次上门预警，MQ定时发送时间
     * @param startDate 当前日期
     * @param endDate 下次上门时间
     * @return
     */
    public static Date getStartDeliverTime(Date startDate, Date endDate) {
        // 下次上门时间早上8点
        Date endDay = getBaseDefer(endDate, 0 , 8);
        // 如果比开始时间小，说明当天上门，现在已经过了8点，不需要发送预警消息
        if (endDay.getTime() <= startDate.getTime()) {
            return null;
        }
        // 下次上门时间前一天早上8点
        Date beforeDay = getBaseDefer(endDate, -1 , 8);
        // 如果前一天早上8点小于开始时间，则返回下次上门时间早上8点
        if (beforeDay.getTime() <= startDate.getTime()) {
            return endDay;
        } else {
            // 判断开始时间和下次上门时间前一天相差多少天
            int diff = (int) DateUtil.getTimespan(startDate, beforeDay, DateUtil.UNIT_DAY);
            // 如果相差小于6天，则mq定时发送时间为前一天8点
            if (diff < 6) {
                return beforeDay;
            } else {
                // 否则mq定时发送时间为开始时间加6天，早上8点
                Date startDay = getBaseDefer(startDate, 6, 8);
                return startDay;
            }
        }
    }

    /**
     * 判断是否需要发送预警消息
     * 0代表当天上门需要发送
     * 1代表明天上门需要发送，重新进入队列，明天需要再次发送一次
     * 2代表明天以后上门不需要发送，重新进入队列
     * @param startDate
     * @param endDate
     * @return
     */
    public static int isSendWarn(Date startDate, Date endDate) {
        // 两个时间都取早上8点钟
        Date startDay = getBaseDefer(startDate, 0, 8);
        Date endDay = getBaseDefer(endDate, 0 , 8);
        // 判断是否相等，如果相等则需要发送预警消息
        if (startDay.getTime() == endDay.getTime()) {
            return 0;
        }
        // 下次上门时间前一天早上8点
        Date beforeDay = getBaseDefer(endDate, -1 , 8);
        // 下次上门时间前一天早上8点等于今天早上8点，则需要发送预警消息
        if (startDay.getTime() == beforeDay.getTime()) {
            return 1;
        } else {
            return 2;
        }
    }

    /**
     * 获取当前日期本月第一天 00:00:00:000
     * @param date
     * @return
     */
    public static Date getMonthFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取当前日期本月最后一天 23:59:59:999
     * @param date
     * @return
     */
    public static Date getMonthLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取当前时间到月底23:59:59:999 的时间（秒）
     * @param date
     * @return
     */
    public static long getMonthLastDayDeffer(Date date) {
        Date lastDay = getMonthLastDay(date);
        long deffer = lastDay.getTime() - date.getTime();
        return deffer/1000;
    }

    public static void main(String[] args) {

        int offset = new Random().nextInt(3600);
        Long deffer = DateTimeUtil.getMonthLastDayDeffer(DateUtil.getNow()) + offset;
        System.out.println(deffer);
    }

}
